module nazo.savelist;
/**
 * License: Public Domain
 */
import std.stdio, std.regexp, nazo.file, std.date, nazo.string;

/**
 * 保存するリスト
 */
class SaveList{
  public{
    //パス
    private string path;
    //内容
    private string content="";
    string getContent(){
      return content;
    }
    size_t length(){
      return content.length==0?0:count(content, "\n") + 1;
    }
    string[] opSlice(size_t x, size_t y){
      return getList()[x..y];
    }
    string opIndex(size_t x){
      return getList()[x];
    }
    int opApply(int delegate(ref string) dg){
      int rv = 0;
      getBefores(content,'\n',delegate uint(string str){
        rv = dg(str);
        return rv;
      });
      return rv;
    }
    int opApply(int delegate(ref uint, ref string) dg){
      int rv = 0;
      uint i = 0;
      getBefores(content,'\n',delegate uint(string str){
        rv = dg(i, str);
        i++;
        return rv;
      });
      return rv;
    }
    int opApplyReverse(int delegate(ref string) dg){
      int rv = 0;
      getAfters(content,'\n',delegate uint(string str){
        rv = dg(str);
        return rv;
      });
      return rv;
    }
    int opApplyReverse(int delegate(ref uint, ref string) dg){
      int rv = 0;
      uint i = length-1;
      getAfters(content,'\n',delegate uint(string str){
        rv = dg(i, str);
        i--;
        return rv;
      });
      return rv;
    }
    ///ソートされたリストとして取得
    string[] sort(){
      return getList().sort;
    }
    ///リストとして取得
    string[] getList(){
      return splitlines(this.content);
    }
    ///リストとして設定
    void setList(string[] list){
      this.content=std.string.join(list, \n);
      std.file.write(path,content);
    }
    ///追加
    void append(string title){
      .append(path,"\n"~title);
      this.content~="\n"~title;
    }
    ///削除
    void remove(string line){
      string _content="";
      foreach(string i; this){///FIXME: 高速化可能
        if(i!=line && i!=""){
          _content~=i~"\n";
        }
      }
      this.content=_content;
      if(this.content!="")
        std.file.write(path,this.content);
      else if(isExist)
        std.file.remove(path);
    }
    ///全て削除
    void removeList(){
      if(isExist){
        std.file.remove(path);
        this.content="";
      }
    }
    ///ファイルが存在するか
    bool isExist(){
      if(exists(path) && isfile(path))
        return true;
      return false;
    }
    ///更新日時
    d_time lastModified(){
      return getLastWriteTime(path);
    }
    ///コンストラクタ
    this(string fileName){
      this.path=fileName;
      if(!isExist())return;
      string t=cast(string)(.read(path));
      t = t.replace("\r","").replace("\n\n","\n");///FIXME: 高速化
      if(t.length>0&&t[0]=='\n')
        t=t[1..$];
      if(t.length>0&&t[$-1] == '\n')
        t=t[0..$-1];
      this.content=t;
    }
  }
}

class TSaveList(string filename):SaveList{
  public{
    ///ファイル名の取得
    static string getFileName(){
      return filename;
    }
    ///コンストラクタ
    this(){
      super(getFileName());
    }
  }
}

class TSaveList(string filenamebefore, string filenameafter):SaveList{
  public{
    ///ファイル名の取得
    static string getFileName(string name){
      return filenamebefore~name~filenameafter; 
    }
    ///コンストラクタ
    this(string name){
      super(getFileName(name));
    }
  }
}
